using System;
using System.Collections.Generic;
using System.IO;
using System.Linq;
using System.Text;
using CarlosAg.ExcelXmlWriter;
using Medianamik.Globalization;
using Medianamik.Globalization.Utilities;
using Moq;
using NUnit.Framework;

namespace Medianamik.Tests.Unit.Globalization.Utilities
{
    [TestFixture]
    public class ExcelResourceConverterTest
    {
        [Test]
        public void ToResource_should_return_resource_in_correct_format()
        {
            var expectedId = "id";
            var expectedResourceSet = "resourceSet";
            var expectedCulture = "culture";
            var expectedValue = "value";

            var wb = new Workbook();
            wb.Worksheets.Add(expectedResourceSet);
            
            var row = new WorksheetRow();
            row.Cells.Add(new WorksheetCell(expectedId, DataType.String));
            row.Cells.Add(new WorksheetCell(expectedCulture, DataType.String));
            row.Cells.Add(new WorksheetCell(expectedValue, DataType.String));
            
            var resource = row.ToResource(wb.Worksheets[0].Name);

            Assert.That(resource.Id, Is.EqualTo(expectedId));
            Assert.That(resource.CultureName, Is.EqualTo(expectedCulture));
            Assert.That(resource.Value, Is.EqualTo(expectedValue));
            Assert.That(resource.ResourceSet, Is.EqualTo(expectedResourceSet));
        }
        [Test] 
        public void ToResource_should_throw_ArgumentNullException_when_row_is_null_or_its_worksheet_is_null()
        {
            WorksheetRow row = null;
            Assert.Throws<ArgumentNullException>(() => row.ToResource(null));
            row = new WorksheetRow();
            Assert.Throws<ArgumentNullException>(() => row.ToResource(null));
        }
        [Test]
        public void ToResource_should_throw_ArgumentException_when_row_cell_count_is_smaller_than_2()
        {
            var wb = new Workbook();
            wb.Worksheets.Add("resourceSet");
            var row = new WorksheetRow();
            row.Cells.Add(new WorksheetCell());
            
            
            Assert.Throws<ArgumentException>(() => row.ToResource(wb.Worksheets[0].Name));
        }
        [Test]
        public void ToResource_should_return_null_when_row_cell_count_equals_2()
        {
            var wb = new Workbook();
            wb.Worksheets.Add("resourceSet");
            var row = new WorksheetRow();
            row.Cells.Add(new WorksheetCell());
            row.Cells.Add(new WorksheetCell());

            Assert.That(row.ToResource(wb.Worksheets[0].Name), Is.Null);
        }

        [Test]
        public void ToResource_should_return_null_when_thors_row_value_is_null_or_empty()
        {
            var wb = new Workbook();
            wb.Worksheets.Add("resourceSet");
            var row = new WorksheetRow();
            row.Cells.Add(new WorksheetCell());
            row.Cells.Add(new WorksheetCell());
            row.Cells.Add(new WorksheetCell());

            Assert.That(row.ToResource(wb.Worksheets[0].Name), Is.Null);
        }
        [Test]
        public void ToResources_should_return_same_count_than_workbook_rowcount_but_remove_rows_with_empty_values()
        {
            var expectedId = "id";
            var expectedResourceSet = "resourceSet";
            var expectedCulture = "culture";
            var expectedValue = "value";

            var wb = new Workbook();
            var ws = wb.Worksheets.Add(expectedResourceSet);

            var row = new WorksheetRow();
            row.Cells.Add(new WorksheetCell("ResourceSet ID :", DataType.String));
            row.Cells.Add(new WorksheetCell(expectedResourceSet, DataType.String));
            ws.Table.Rows.Add(row);
            ws.Table.Rows.Add(new WorksheetRow());
            
            int i;
            for (i = 0; i < 5; i++)
            {
                row = new WorksheetRow();
                
                row.Cells.Add(new WorksheetCell(expectedId + i, DataType.String));
                row.Cells.Add(new WorksheetCell(expectedCulture + i, DataType.String));
                row.Cells.Add(new WorksheetCell(expectedValue + i, DataType.String));
                ws.Table.Rows.Add(row);
            }
            
            //ajoute des ressources sans valeur (voir export sous plusieurs langues)
            int j;
            for (j = 0; j < 3; j++)
            {
                row = new WorksheetRow();

                row.Cells.Add(new WorksheetCell(expectedId + (i + j), DataType.String));
                row.Cells.Add(new WorksheetCell(expectedCulture + (i + j), DataType.String));
                row.Cells.Add(new WorksheetCell(String.Empty, DataType.String));
                ws.Table.Rows.Add(row);
            }

            var resources = wb.ToResources();
            int cpt = 0;
            foreach(var resource in resources)
            {
                Assert.That(resource.Id, Is.EqualTo(expectedId + cpt));
                Assert.That(resource.CultureName, Is.EqualTo(expectedCulture + cpt));
                Assert.That(resource.Value, Is.EqualTo(expectedValue + cpt));
                Assert.That(resource.ResourceSet, Is.EqualTo(expectedResourceSet));
                cpt++;
            }
        }
        [Test]
        public void ToWorksheetRow_should_return_a_row_in_valid_format()
        {
            var expectedId = "id";
            var expectedResourceSet = "resourceSet";
            var expectedCulture = "culture";
            var expectedValue = "value";

            var wb = new Workbook();
            wb.Worksheets.Add(expectedResourceSet);
            var resource = new Resource(expectedId, expectedCulture, expectedValue, expectedResourceSet);
                              
            var actualRow = resource.ToWorksheetRow();

            Assert.That(actualRow.Cells[0].Data.Text, Is.EqualTo(expectedId));
            Assert.That(actualRow.Cells[1].Data.Text, Is.EqualTo(expectedCulture));
            Assert.That(actualRow.Cells[2].Data.Text, Is.EqualTo(expectedValue));
            Assert.That(wb.Worksheets[0].Name, Is.EqualTo(expectedResourceSet));
        }
        [Test]
        public void ToWorksheetRow_should_throw_ArgumentNullException_when_resource_is_null()
        {
            Resource resource = null;
            Assert.Throws<ArgumentNullException>(() => resource.ToWorksheetRow());
        }
        [Test]
        public void ToResources_should_give_the_first_row_second_cell_of_the_current_worksheet_as_ResourceSet()
        {
            var expectedId = "id";
            var expectedResourceSet = "resourceSet";
            var expectedCulture = "culture";
            var expectedValue = "value";

            var wb = new Workbook();
            wb.Worksheets.Add(expectedResourceSet);
            var ws = wb.Worksheets[0];

            var row = new WorksheetRow();
            row.Cells.Add(new WorksheetCell("ResourceSet ID : ", DataType.String));
            row.Cells.Add(new WorksheetCell(expectedResourceSet, DataType.String));
            ws.Table.Rows.Add(row);
            ws.Table.Rows.Add(new WorksheetRow());

            var resource = new Resource(expectedId, expectedCulture, expectedValue, expectedResourceSet);
            ws.Table.Rows.Add(resource.ToWorksheetRow());

            var actualResources = wb.ToResources();

            Assert.That(actualResources.First().ResourceSet, Is.EqualTo(expectedResourceSet));
        }
    }
}